package com.lsl.myfilemanager;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

import com.lsl.myfilemanager.activity.VideoActivity;
import com.lsl.myfilemanager.adapter.FileListAdapter;
import com.lsl.myfilemanager.bean.FileInfo;
import com.lsl.myfilemanager.util.FileScanUtil;
import com.lsl.myfilemanager.util.FileTypeUtil;
import com.lsl.myfilemanager.util.FormatTime;
import com.lsl.myfilemanager.util.RecycleItemClickListener;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

/**
 * author lishilin
 * date 2023/8/10
 * desc 文件管理器主要代码
 */
public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private List<View> fileViews;
    private ViewPager fileViewPager;
    private RadioGroup fileRadioGroup;
    private RadioButton allBtn, picBtn, musicBtn, videoBtn, apkBtn;
    private TextView directoryPath;
    private RadioButton selectedBtn;
    private View allFileView, picFileView, musicFileView, videoFileView, apkFileView;
    private RecyclerView allFileRecycle, picRecycle, musicRecycle, videoRecycle, apkRecycle;
    private Dialog imageDialog, musicDialog;
    private ImageButton playOrPauseBtn, preSongBtn, nextSongBtn, backBtn;
    private View navigatorPathView;

    private List<FileInfo> currentFileList;
    private Stack<String> directoryStack;
    private Stack<List<FileInfo>> fileListStack;
    private final int STORAGE_PERMISSION_REQUEST_CODE = 110;
    private List<FileInfo> allFileData, picFileData, musicFileData, videoFileData, apkFileData;
    private MediaPlayer musicPlayer;
    private boolean musicPlayFlag = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        openPermissionSettings();
        initRecycleView();
        setFileViewPager();//设置ViewPager以及监听页面滑动
        setButtonClickListener();//设置顶部tab的点击监听器，更新viewPager的当前项
    }

    private void initView() {
        allFileData = new ArrayList<>();
        picFileData = new ArrayList<>();
        musicFileData = new ArrayList<>();
        videoFileData = new ArrayList<>();
        apkFileData = new ArrayList<>();
        directoryStack = new Stack<>();
        fileListStack = new Stack<>();
        directoryStack.push("/sdcard");
        fileViewPager = findViewById(R.id.fileViewpager);
        fileRadioGroup = findViewById(R.id.fileTabRg);
        directoryPath = findViewById(R.id.directorStack);
        allBtn = findViewById(R.id.rbAllFile);
        picBtn = findViewById(R.id.rbPicture);
        musicBtn = findViewById(R.id.rbMusic);
        videoBtn = findViewById(R.id.rbVideo);
        apkBtn = findViewById(R.id.rbApk);
        navigatorPathView = (View) findViewById(R.id.navigatorPath);
        ImageButton closeFileMagBtn = findViewById(R.id.closeFileMag);
        backBtn = findViewById(R.id.back);
        imageDialog = new Dialog(this);
        musicDialog = new Dialog(this);
        fileViews = new ArrayList<>();
        allFileView = LayoutInflater.from(this).inflate(R.layout.all_view, null);
        picFileView = LayoutInflater.from(this).inflate(R.layout.picture_view, null);
        musicFileView = LayoutInflater.from(this).inflate(R.layout.music_view, null);
        videoFileView = LayoutInflater.from(this).inflate(R.layout.video_view, null);
        apkFileView = LayoutInflater.from(this).inflate(R.layout.apk_view, null);
        fileViews.add(allFileView);
        fileViews.add(picFileView);
        fileViews.add(musicFileView);
        fileViews.add(videoFileView);
        fileViews.add(apkFileView);
        closeFileMagBtn.setOnClickListener(this);
        backBtn.setOnClickListener(this);
        selectedBtn = allBtn;//初始化默认选中的菜单
        selectedBtn.setSelected(true);
    }

    private void initRecycleView() {
        allFileRecycle = allFileView.findViewById(R.id.recycler_view);
        picRecycle = picFileView.findViewById(R.id.recycler_view);
        musicRecycle = musicFileView.findViewById(R.id.recycler_view);
        videoRecycle = videoFileView.findViewById(R.id.recycler_view);
        apkRecycle = apkFileView.findViewById(R.id.recycler_view);
        //设置适配器
        allFileRecycle.setAdapter(new FileListAdapter(allFileData));
        picRecycle.setAdapter(new FileListAdapter(picFileData));
        musicRecycle.setAdapter(new FileListAdapter(musicFileData));
        videoRecycle.setAdapter(new FileListAdapter(videoFileData));
        apkRecycle.setAdapter(new FileListAdapter(apkFileData));
        //为每一个recycleView设置监听器
        allFileRecycle.addOnItemTouchListener(setRecycleItemClickListener(allFileRecycle));
        picRecycle.addOnItemTouchListener(setRecycleItemClickListener(allFileRecycle));
        musicRecycle.addOnItemTouchListener(setRecycleItemClickListener(allFileRecycle));
        videoRecycle.addOnItemTouchListener(setRecycleItemClickListener(videoRecycle));
        apkRecycle.addOnItemTouchListener(setRecycleItemClickListener(apkRecycle));
        //设置布局管理器
        allFileRecycle.setLayoutManager(new GridLayoutManager(this, 5));
        picRecycle.setLayoutManager(new GridLayoutManager(this, 5));
        musicRecycle.setLayoutManager(new GridLayoutManager(this, 5));
        videoRecycle.setLayoutManager(new GridLayoutManager(this, 5));
        apkRecycle.setLayoutManager(new GridLayoutManager(this, 5));
        if (allFileData.size() > 0) {
            updateRecycleViewData(allFileRecycle, allFileData);
        }
    }

    /**
     * 发生页面滑动操作时更新顶部tab栏的选中状态,同时刷新recycle数据列表
     * date 2023/8/10
     */
    private void setFileViewPager() {
        fileViewPager.setAdapter(new myViewPagerAdapter());
        fileViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            }

            @Override
            public void onPageSelected(int position) {
                switch (position) {
                    case 0:
                        updateSelectBtn(allBtn);
                        updateRecycleViewData(allFileRecycle, allFileData);
                        currentFileList = allFileData;
                        navigatorPathView.setVisibility(View.VISIBLE);
                        break;
                    case 1:
                        updateSelectBtn(picBtn);
                        updateRecycleViewData(picRecycle, picFileData);
                        currentFileList = picFileData;
                        navigatorPathView.setVisibility(View.INVISIBLE);
                        break;
                    case 2:
                        updateSelectBtn(musicBtn);
                        updateRecycleViewData(musicRecycle, musicFileData);
                        currentFileList = musicFileData;
                        navigatorPathView.setVisibility(View.INVISIBLE);
                        break;
                    case 3:
                        updateSelectBtn(videoBtn);
                        updateRecycleViewData(videoRecycle, videoFileData);
                        currentFileList = videoFileData;
                        navigatorPathView.setVisibility(View.INVISIBLE);
                        break;
                    case 4:
                        updateSelectBtn(apkBtn);
                        updateRecycleViewData(apkRecycle, apkFileData);
                        currentFileList = apkFileData;
                        navigatorPathView.setVisibility(View.INVISIBLE);
                        break;
                    default:
                        break;
                }
            }

            @Override
            public void onPageScrollStateChanged(int state) {
            }
        });
    }

    private void updateSelectBtn(RadioButton selectedBtn) {
        if (this.selectedBtn != null) {
            this.selectedBtn.setSelected(false);
            this.selectedBtn.setChecked(false);
        }
        selectedBtn.setSelected(true);
        selectedBtn.setChecked(true);
        this.selectedBtn = selectedBtn;
    }

    /**
     * 更新recycleView 的数据
     * date 2023/8/11
     *
     * @param selectedRecycle
     * @param currentFileData
     */
    private void updateRecycleViewData(RecyclerView selectedRecycle, List<FileInfo> currentFileData) {
        if (selectedRecycle == null) {
            return;
        }
        FileListAdapter adapter = (FileListAdapter) selectedRecycle.getAdapter();
        if (adapter == null) {
            adapter = new FileListAdapter(currentFileData);
            selectedRecycle.setAdapter(adapter);
        } else {
            adapter.updateData(currentFileData);
        }
    }

    /**
     * viewPager适配器
     * date 2023/8/10
     */
    private class myViewPagerAdapter extends PagerAdapter {
        @Override
        public int getCount() {
            return fileViews.size();
        }

        @Override
        public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
            return view == object;
        }

        //加载第三屏会销毁第一屏,隔屏销毁
        @Override
        public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
            container.removeView(fileViews.get(position));
        }

        @NonNull
        @Override
        public Object instantiateItem(@NonNull ViewGroup container, int position) {
            container.addView(fileViews.get(position));
            return fileViews.get(position);
        }
    }

    /**
     * 设置文件菜单的点击监听器
     * date 2023/8/10
     */
    private void setButtonClickListener() {
        fileRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                switch (checkedId) {
                    case R.id.rbAllFile:
                        fileViewPager.setCurrentItem(0);
                        break;
                    case R.id.rbPicture:
                        fileViewPager.setCurrentItem(1);
                        break;
                    case R.id.rbMusic:
                        fileViewPager.setCurrentItem(2);
                        break;
                    case R.id.rbVideo:
                        fileViewPager.setCurrentItem(3);
                        break;
                    case R.id.rbApk:
                        fileViewPager.setCurrentItem(4);
                        break;
                    default:
                        break;
                }
            }
        });
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.closeFileMag:
                finish();
                break;
            case R.id.back:
                //子页面回退时刷新recycleView文件列表数据,并更新显示的Path
                if (directoryStack.size() <= 1 || fileListStack.size() <= 1) {
                    return;
                }
                directoryStack.pop();
                directoryPath.setText(directoryStack.peek());
                fileListStack.pop();
                List<FileInfo> preList = fileListStack.peek();
                currentFileList = preList;
                allFileData = preList;
                updateRecycleViewData(allFileRecycle, currentFileList);
                break;
        }
    }

    /**
     * 在页面初始化之前加载文件列表,多线程加载
     * date 2023/8/11
     */
    private void scanFile() {
        //扫描全部文件
        String rootFilePath = "/sdcard/";
        allFileData = FileScanUtil.scanRootFiles(rootFilePath);
        currentFileList = allFileData;
        //updateRecycleViewData(allFileRecycle, allFileData);
        fileListStack.push(allFileData);
        new Thread(new Runnable() {
            @Override
            public void run() {
                picFileData = FileScanUtil.scanImageFiles(MainActivity.this);
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                musicFileData = FileScanUtil.scanAudioFiles(MainActivity.this);
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                videoFileData = FileScanUtil.scanVideoFiles(MainActivity.this);
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                String path = "/sdcard";
                apkFileData = FileScanUtil.getApkFile(path);
            }
        }).start();
    }

    /**
     * 监听recycleView的点击事件
     * date 2023/8/14 由touch修改为click类型，防止touch影响recycleView的滑动
     * @param currentRecyclerView
     * @return
     */
    private RecycleItemClickListener setRecycleItemClickListener(RecyclerView currentRecyclerView) {
        RecycleItemClickListener recycleItemClickListener = new RecycleItemClickListener(this, currentRecyclerView, new RecycleItemClickListener.OnItemClickListener() {
            @Override
            public void onItemClick(View view, int position) {
                Log.d("执行列表点击事件：", "位置" + position);
                FileInfo fileInfo = currentFileList.get(position);
                String filePath = fileInfo.getPath();
                String fileName = fileInfo.getFileName();
                switch (fileInfo.getType()) {
                    case FileTypeUtil.DIRECTORY:
                        //目录，打开子目录扫描子目录文件
                        List<FileInfo> list = FileScanUtil.scanRootFiles(filePath);
                        directoryStack.push(filePath);
                        directoryPath.setText(filePath);
                        fileListStack.push(list);
                        allFileData = list;
                        currentFileList = list;
                        updateRecycleViewData(allFileRecycle, list);
                        break;
                    case FileTypeUtil.PICTURE:
                        showImageDialog(filePath);
                        break;
                    case FileTypeUtil.MUSIC:
                        openMusicDialog(filePath, fileName);
                        break;
                    case FileTypeUtil.VIDEO:
                        //打开一个视频activity
                        Intent intent = new Intent(MainActivity.this, VideoActivity.class);
                        intent.putExtra("path", filePath);
                        intent.putExtra("name", fileName);
                        startActivity(intent);
                        break;
                    case FileTypeUtil.APK:
                        installApk(filePath);
                        break;
                }
            }

            @Override
            public void onLongItemClick(View view, int position) {
            }
        });
        return recycleItemClickListener;
    }

    private void installApk(String url) {
        Intent intent = new Intent();
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setAction(Intent.ACTION_VIEW);
        File apkFile = new File(url);
        Uri uri = null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            uri = FileProvider.getUriForFile(this, this.getPackageName()
                    + ".fileprovider", apkFile);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        } else {
            uri = Uri.fromFile(apkFile);
        }
        intent.setDataAndType(uri, "application/vnd.android.package-archive");
        this.startActivity(intent);
    }


    /**
     * 展示图片
     * date 2023/8/14
     *
     * @param imagePath
     */
    private void showImageDialog(String imagePath) {
        if (imageDialog == null) {
            return;
        }
        Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
        imageDialog.setContentView(R.layout.image_dialog);
        ImageView imageView = imageDialog.findViewById(R.id.showImage);
        imageView.setImageBitmap(bitmap);
        imageDialog.show();
        //监听关闭按钮
        ImageButton close = imageDialog.findViewById(R.id.closeImageView);
        close.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                imageDialog.cancel();
            }
        });
    }

    /**
     * 启动音乐播放器播放音乐
     * date 2023/8/14
     *
     * @param path
     */
    private void openMusicDialog(String path, String musicName) {
        musicDialog.setContentView(R.layout.music_dialog);
        musicPlayer = new MediaPlayer();
        try {
            musicPlayer.setDataSource(path);
        } catch (IOException e) {
            e.printStackTrace();
        }
        musicPlayer.prepareAsync();
        musicDialog.show();
        ImageButton close = musicDialog.findViewById(R.id.closeMusic);
        playOrPauseBtn = musicDialog.findViewById(R.id.play_or_stop);
        preSongBtn = musicDialog.findViewById(R.id.pre_song);
        nextSongBtn = musicDialog.findViewById(R.id.next_song);
        TextView currentProcessView = musicDialog.findViewById(R.id.current_process);
        TextView totalProcessView = musicDialog.findViewById(R.id.max_process);
        SeekBar seekBar = musicDialog.findViewById(R.id.music_seekBar);
        TextView title = musicDialog.findViewById(R.id.musicTitle);
        title.setText(musicName);
        playOrPauseBtn.setImageResource(R.drawable.pause);
        close.setOnClickListener(musicListener());
        playOrPauseBtn.setOnClickListener(musicListener());
        preSongBtn.setOnClickListener(musicListener());
        nextSongBtn.setOnClickListener(musicListener());
        //监听音乐加载
        musicPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mp) {
                musicPlayFlag = true;
                totalProcessView.setText(FormatTime.SecondToSongTime(musicPlayer.getDuration() / 1000));//设置进度条总时长
                seekBar.setMax(musicPlayer.getDuration());
                musicPlayer.start();
                @SuppressLint("HandlerLeak")
                Handler mhandler = new Handler() {
                    @Override
                    public void handleMessage(Message message) {
                        if (message.what == 1) {
                            int currentProcess = musicPlayer.getCurrentPosition();
                            seekBar.setProgress(currentProcess);
                            currentProcessView.setText(FormatTime.SecondToSongTime(currentProcess / 1000));//设置进度条当前时长
                        }
                    }
                };
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        while (musicPlayFlag) {
                            Message message = new Message();
                            message.what = 1;
                            mhandler.sendMessage(message);
                            try {
                                Thread.sleep(100);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }).start();
                //监听进度条滑动
                seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                    @Override
                    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                    }

                    @Override
                    public void onStartTrackingTouch(SeekBar seekBar) {
                    }

                    @Override
                    public void onStopTrackingTouch(SeekBar seekBar) {
                        int current = seekBar.getProgress();
                        currentProcessView.setText(FormatTime.SecondToSongTime(current / 1000));
                        musicPlayer.seekTo(current);
                    }
                });
            }
        });
        musicPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
                playOrPauseBtn.setImageResource(R.drawable.play);
            }
        });
    }

    /**
     * 音乐播放器UI监听器
     *
     * @return
     */
    private View.OnClickListener musicListener() {
        return new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                switch (v.getId()) {
                    case R.id.closeMusic:
                        musicDialog.cancel();
                        musicPlayFlag = false;//停止更新进度条进程
                        if (musicPlayer.isPlaying()) {
                            musicPlayer.stop();
                        }
                        musicPlayer.release();
                        musicPlayer = null;
                        break;
                    case R.id.play_or_stop:
                        if (musicPlayer.isPlaying()) {
                            playOrPauseBtn.setImageResource(R.drawable.play);
                            musicPlayer.pause();
                        } else {
                            playOrPauseBtn.setImageResource(R.drawable.pause);
                            musicPlayer.start();
                        }
                        break;
                    case R.id.pre_song:
                    case R.id.next_song:
                        musicPlayer.seekTo(0);
                        break;
                }
            }
        };
    }

    /**
     * 获取读取外部存储权限
     * date 2023/8月11日改
     */
    private void requestPermissions() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
            scanFile();
        } else {
            Log.i("权限", "没有权限！");
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSION_REQUEST_CODE);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == STORAGE_PERMISSION_REQUEST_CODE) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                scanFile();
            } else {
                Toast.makeText(this, "你已拒绝相关权限", Toast.LENGTH_SHORT);
            }
        }
    }

    /**
     * 手动跳转到权限管理器申请管理所有文件的权限
     * date 2023/8/14
     */
    private static final int PERMISSION_REQUEST_CODE = 123;
    private static final int REQUEST_CODE_UNKNOWN_APP = 124;
    // 打开权限管理器
    private void openPermissionSettings() {
        //判断当前系统版本是否大于或等于安卓11
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            if (!Environment.isExternalStorageManager()) {
                Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
                Uri uri = Uri.fromParts("package", getPackageName(), null);
                intent.setData(uri);
                startActivityForResult(intent, PERMISSION_REQUEST_CODE);
            } else {
                scanFile();
            }
        } else {
            //直接申请权限
            requestPermissions();
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            if (!this.getPackageManager().canRequestPackageInstalls()) {
                // 请求安装未知来源应用的权限
                Intent permissionIntent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES,
                        Uri.parse("package:" + this.getPackageName()));
                startActivityForResult(permissionIntent, REQUEST_CODE_UNKNOWN_APP);
            }
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == PERMISSION_REQUEST_CODE) {
            // 检查所需的权限是否已被授予
            if (Environment.isExternalStorageManager()) {
                requestPermissions();
            } else {
                // 用户仍然未授予所需的权限
                Toast toast = Toast.makeText(this, "你未授权相应权限！无法正常使用！", Toast.LENGTH_LONG);
                toast.show();
                requestPermissions();
            }
        }
        if (requestCode == REQUEST_CODE_UNKNOWN_APP){
            if (!this.getPackageManager().canRequestPackageInstalls()){
//                Toast toast = Toast.makeText(this, "你未授权安装权限！无法正常使用！", Toast.LENGTH_LONG);
//                toast.show();
            }
        }
    }

}